home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / source.exe / POSIX / MAKE / MAKE.C < prev    next >
C/C++ Source or Header  |  1992-06-29  |  27KB  |  848 lines

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  3.  * Copyright (c) 1988, 1989 by Adam de Boor
  4.  * Copyright (c) 1989 by Berkeley Softworks
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Adam de Boor.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  */
  38.  
  39. #ifndef lint
  40. static char sccsid[] = "@(#)make.c    5.3 (Berkeley) 6/1/90";
  41. #endif /* not lint */
  42.  
  43. /*-
  44.  * make.c --
  45.  *    The functions which perform the examination of targets and
  46.  *    their suitability for creation
  47.  *
  48.  * Interface:
  49.  *    Make_Run             Initialize things for the module and recreate
  50.  *                          whatever needs recreating. Returns TRUE if
  51.  *                            work was (or would have been) done and FALSE
  52.  *                          otherwise.
  53.  *
  54.  *    Make_Update            Update all parents of a given child. Performs
  55.  *                          various bookkeeping chores like the updating
  56.  *                          of the cmtime field of the parent, filling
  57.  *                          of the IMPSRC context variable, etc. It will
  58.  *                          place the parent on the toBeMade queue if it
  59.  *                          should be.
  60.  *
  61.  *    Make_TimeStamp            Function to set the parent's cmtime field
  62.  *                          based on a child's modification time.
  63.  *
  64.  *    Make_DoAllVar            Set up the various local variables for a
  65.  *                          target, including the .ALLSRC variable, making
  66.  *                          sure that any variable that needs to exist
  67.  *                          at the very least has the empty value.
  68.  *
  69.  *    Make_OODate             Determine if a target is out-of-date.
  70.  *
  71.  *    Make_HandleUse            See if a child is a .USE node for a parent
  72.  *                and perform the .USE actions if so.
  73.  */
  74.  
  75. #include    "make.h"
  76.  
  77. static Lst         toBeMade;    /* The current fringe of the graph. These
  78.                  * are nodes which await examination by
  79.                  * MakeOODate. It is added to by
  80.                  * Make_Update and subtracted from by
  81.                  * MakeStartJobs */
  82. static int      numNodes;       /* Number of nodes to be processed. If this
  83.                  * is non-zero when Job_Empty() returns
  84.                  * TRUE, there's a cycle in the graph */
  85.  
  86. /*-
  87.  *-----------------------------------------------------------------------
  88.  * Make_TimeStamp --
  89.  *    Set the cmtime field of a parent node based on the mtime stamp in its
  90.  *    child. Called from MakeOODate via Lst_ForEach. 
  91.  *
  92.  * Results:
  93.  *    Always returns 0. 
  94.  *
  95.  * Side Effects:
  96.  *    The cmtime of the parent node will be changed if the mtime
  97.  *    field of the child is greater than it.
  98.  *-----------------------------------------------------------------------
  99.  */
  100. int
  101. Make_TimeStamp (pgn, cgn)
  102.     register GNode *pgn;    /* the current parent */
  103.     register GNode *cgn;    /* the child we've just examined */
  104. {
  105.     if (cgn->mtime > pgn->cmtime) {
  106.     pgn->cmtime = cgn->mtime;
  107.     }
  108.     return (0);
  109. }
  110.  
  111. /*-
  112.  *-----------------------------------------------------------------------
  113.  * Make_OODate --
  114.  *    See if a given node is out of date with respect to its sources.
  115.  *    Used by Make_Run when deciding which nodes to place on the
  116.  *    toBeMade queue initially and by Make_Update to screen out USE and
  117.  *    EXEC nodes. In the latter case, however, any other sort of node
  118.  *    must be considered out-of-date since at least one of its children
  119.  *    will have been recreated.
  120.  *
  121.  * Results:
  122.  *    TRUE if the node is out of date. FALSE otherwise. 
  123.  *
  124.  * Side Effects:
  125.  *    The mtime field of the node and the cmtime field of its parents
  126.  *    will/may be changed.
  127.  *-----------------------------------------------------------------------
  128.  */
  129. Boolean
  130. Make_OODate (gn)
  131.     register GNode *gn;          /* the node to check */
  132. {
  133.     Boolean         oodate;
  134.  
  135.     /*
  136.      * Certain types of targets needn't even be sought as their datedness
  137.      * doesn't depend on their modification time...
  138.      */
  139.     if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC)) == 0) {
  140.     (void) Dir_MTime (gn);
  141.     if (DEBUG(MAKE)) {
  142.         if (gn->mtime != 0) {
  143.         printf ("modified %s...", Targ_FmtTime(gn->mtime));
  144.         } else {
  145.         printf ("non-existent...");
  146.         }
  147.     }
  148.     }
  149.  
  150.     /*
  151.      * A target is remade in one of the following circumstances:
  152.      *    its modification time is smaller than that of its youngest child
  153.      *        and it would actually be run (has commands or type OP_NOP)
  154.      *    it's the object of a force operator
  155.      *    it has no children, was on the lhs of an operator and doesn't exist
  156.      *        already.
  157.      *
  158.      * Libraries are only considered out-of-date if the archive module says
  159.      * they are.
  160.      *
  161.      * These weird rules are brought to you by Backward-Compatability and
  162.      * the strange people who wrote 'Make'.
  163.      */
  164.     if (gn->type & OP_USE) {
  165.     /*
  166.      * If the node is a USE node it is *never* out of date
  167.      * no matter *what*.
  168.      */
  169.     if (DEBUG(MAKE)) {
  170.         printf(".USE node...");
  171.     }
  172.     oodate = FALSE;
  173.     } else if (gn->type & OP_LIB) {
  174.     if (DEBUG(MAKE)) {
  175.         printf("library...");
  176.     }
  177.     oodate = Arch_LibOODate (gn);
  178.     } else if (gn->type & OP_JOIN) {
  179.     /*
  180.      * A target with the .JOIN attribute is only considered
  181.      * out-of-date if any of its children was out-of-date.
  182.      */
  183.     if (DEBUG(MAKE)) {
  184.         printf(".JOIN node...");
  185.     }
  186.     oodate = gn->childMade;
  187.     } else if (gn->type & (OP_FORCE|OP_EXEC)) {
  188.     /*
  189.      * A node which is the object of the force (!) operator or which has
  190.      * the .EXEC attribute is always considered out-of-date.
  191.      */
  192.     if (DEBUG(MAKE)) {
  193.         if (gn->type & OP_FORCE) {
  194.         printf("! operator...");
  195.         } else {
  196.         printf(".EXEC node...");
  197.         }
  198.     }
  199.     oodate = TRUE;
  200.     } else if ((gn->mtime < gn->cmtime) ||
  201.            ((gn->cmtime == 0) &&
  202.         ((gn->mtime==0) || (gn->type & OP_DOUBLEDEP))))
  203.     {
  204.     /*
  205.      * A node whose modification time is less than that of its
  206.      * youngest child or that has no children (cmtime == 0) and
  207.      * either doesn't exist (mtime == 0) or was the object of a
  208.      * :: operator is out-of-date. Why? Because that's the way Make does
  209.      * it.
  210.      */
  211.     if (DEBUG(MAKE)) {
  212.         if (gn->mtime < gn->cmtime) {
  213.         printf("modified before source...");
  214.         } else if (gn->mtime == 0) {
  215.         printf("non-existent and no sources...");
  216.         } else {
  217.         printf(":: operator and no sources...");
  218.         }
  219.     }
  220.     oodate = TRUE;
  221.     } else {
  222. #if 0
  223.     /* WHY? */
  224.     if (DEBUG(MAKE)) {
  225.         printf("source %smade...", gn->childMade ? "" : "not ");
  226.     }
  227.     oodate = gn->childMade;
  228. #else
  229.     oodate = FALSE;
  230. #endif /* 0 */
  231.     }
  232.  
  233.     /*
  234.      * If the target isn't out-of-date, the parents need to know its
  235.      * modification time. Note that targets that appear to be out-of-date
  236.      * but aren't, because they have no commands and aren't of type OP_NOP,
  237.      * have their mtime stay below their children's mtime to keep parents from
  238.      * thinking they're out-of-date.
  239.      */
  240.     if (!oodate) {
  241.     Lst_ForEach (gn->parents, Make_TimeStamp, (ClientData)gn);
  242.     }
  243.  
  244.     return (oodate);
  245. }
  246.  
  247. /*-
  248.  *-----------------------------------------------------------------------
  249.  * MakeAddChild  --
  250.  *    Function used by Make_Run to add a child to the list l.
  251.  *    It will only add the child if its make field is FALSE.
  252.  *
  253.  * Results:
  254.  *    Always returns 0
  255.  *
  256.  * Side Effects:
  257.  *    The given list is extended
  258.  *-----------------------------------------------------------------------
  259.  */
  260. static int
  261. MakeAddChild (gn, l)
  262.     GNode          *gn;        /* the node to add */
  263.     Lst            l;        /* the list to which to add it */
  264. {
  265.     if (!gn->make && !(gn->type & OP_USE)) {
  266.     (void)Lst_EnQueue (l, (ClientData)gn);
  267.     }
  268.     return (0);
  269. }
  270.  
  271. /*-
  272.  *-----------------------------------------------------------------------
  273.  * Make_HandleUse --
  274.  *    Function called by Make_Run and SuffApplyTransform on the downward
  275.  *    pass to handle .USE and transformation nodes. A callback function
  276.  *    for Lst_ForEach, it implements the .USE and transformation
  277.  *    functionality by copying the node's commands, type flags
  278.  *    and children to the parent node. Should be called before the
  279.  *    children are enqueued to be looked at by MakeAddChild.
  280.  *
  281.  *    A .USE node is much like an explicit transformation rule, except
  282.  *    its commands are always added to the target node, even if the
  283.  *    target already has commands.
  284.  *
  285.  * Results:
  286.  *    returns 0.
  287.  *
  288.  * Side Effects:
  289.  *    Children and commands may be added to the parent and the parent's
  290.  *    type may be changed.
  291.  *
  292.  *-----------------------------------------------------------------------
  293.  */
  294. int
  295. Make_HandleUse (cgn, pgn)
  296.     register GNode    *cgn;    /* The .USE node */
  297.     register GNode       *pgn;    /* The target of the .USE node */
  298. {
  299.     register GNode    *gn;    /* A child of the .USE node */
  300.     register LstNode    ln;     /* An element in the children list */
  301.  
  302.     if (cgn->type & (OP_USE|OP_TRANSFORM)) {
  303.     if ((cgn->type & OP_USE) || Lst_IsEmpty(pgn->commands)) {
  304.         /*
  305.          * .USE or transformation and target has no commands -- append
  306.          * the child's commands to the parent.
  307.          */
  308.         (void) Lst_Concat (pgn->commands, cgn->commands, LST_CONCNEW);
  309.     }
  310.     
  311.     if (Lst_Open (cgn->children) == SUCCESS) {
  312.         while ((ln = Lst_Next (cgn->children)) != NILLNODE) {
  313.         gn = (GNode *)Lst_Datum (ln);
  314.  
  315.         if (Lst_Member (pgn->children, gn) == NILLNODE) {
  316.             (void) Lst_AtEnd (pgn->children, gn);
  317.             (void) Lst_AtEnd (gn->parents, pgn);
  318.             pgn->unmade += 1;
  319.         }
  320.         }
  321.         Lst_Close (cgn->children);
  322.     }
  323.     
  324.     pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM);
  325.  
  326.     /*
  327.      * This child node is now "made", so we decrement the count of
  328.      * unmade children in the parent... We also remove the child
  329.      * from the parent's list to accurately reflect the number of decent
  330.      * children the parent has. This is used by Make_Run to decide
  331.      * whether to queue the parent or examine its children...
  332.      */
  333.     if (cgn->type & OP_USE) {
  334.         pgn->unmade -= 1;
  335.     }
  336.     }
  337.     return (0);
  338. }
  339.  
  340. /*-
  341.  *-----------------------------------------------------------------------
  342.  * Make_Update  --
  343.  *    Perform update on the parents of a node. Used by JobFinish once
  344.  *    a node has been dealt with and by MakeStartJobs if it finds an
  345.  *    up-to-date node. 
  346.  *
  347.  * Results:
  348.  *    Always returns 0
  349.  *
  350.  * Side Effects:
  351.  *    The unmade field of pgn is decremented and pgn may be placed on
  352.  *    the toBeMade queue if this field becomes 0.
  353.  *
  354.  *     If the child was made, the parent's childMade field will be set true
  355.  *    and its cmtime set to now.
  356.  *
  357.  *    If the child wasn't made, the cmtime field of the parent will be
  358.  *    altered if the child's mtime is big enough.
  359.  *
  360.  *    Finally, if the child is the implied source for the parent, the
  361.  *    parent's IMPSRC variable is set appropriately.
  362.  *
  363.  *-----------------------------------------------------------------------
  364.  */
  365. void
  366. Make_Update (cgn)
  367.     register GNode *cgn;    /* the child node */
  368. {
  369.     register GNode     *pgn;    /* the parent node */
  370.     register char      *cname;    /* the child's name */
  371.     register LstNode    ln;     /* Element in parents and iParents lists */
  372.  
  373.     cname = Var_Value (TARGET, cgn);
  374.  
  375.     /*
  376.      * If the child was actually made, see what its modification time is
  377.      * now -- some rules won't actually update the file. If the file still
  378.      * doesn't exist, make its mtime now.
  379.      */
  380.     if (cgn->made != UPTODATE) {
  381. #ifndef RECHECK
  382.     /*
  383.      * We can't re-stat the thing, but we can at least take care of rules
  384.      * where a target depends on a source that actually creates the
  385.      * target, but only if it has changed, e.g.
  386.      *
  387.      * parse.h : parse.o
  388.      *
  389.      * parse.o : parse.y
  390.      *      yacc -d parse.y
  391.      *      cc -c y.tab.c
  392.      *      mv y.tab.o parse.o
  393.      *      cmp -s y.tab.h parse.h || mv y.tab.h parse.h
  394.      *
  395.      * In this case, if the definitions produced by yacc haven't changed
  396.      * from before, parse.h won't have been updated and cgn->mtime will
  397.      * reflect the current modification time for parse.h. This is
  398.      * something of a kludge, I admit, but it's a useful one..
  399.      * XXX: People like to use a rule like
  400.      *
  401.      * FRC:
  402.      *
  403.      * To force things that depend on FRC to be made, so we have to
  404.      * check for gn->children being empty as well...
  405.      */
  406.     if (!Lst_IsEmpty(cgn->commands) || Lst_IsEmpty(cgn->children)) {
  407.         cgn->mtime = now;
  408.     }
  409. #else
  410.     /*
  411.      * This is what Make does and it's actually a good thing, as it
  412.      * allows rules like
  413.      *
  414.      *    cmp -s y.tab.h parse.h || cp y.tab.h parse.h
  415.      *
  416.      * to function as intended. Unfortunately, thanks to the stateless
  417.      * nature of NFS (by which I mean the loose coupling of two clients
  418.      * using the same file from a common server), there are times
  419.      * when the modification time of a file created on a remote
  420.      * machine will not be modified before the local stat() implied by
  421.      * the Dir_MTime occurs, thus leading us to believe that the file
  422.      * is unchanged, wreaking havoc with files that depend on this one.
  423.      *
  424.      * I have decided it is better to make too much than to make too
  425.      * little, so this stuff is commented out unless you're sure it's ok.
  426.      * -- ardeb 1/12/88
  427.      */
  428.     if (noExecute || Dir_MTime(cgn) == 0) {
  429.         cgn->mtime = now;
  430.     }
  431.     if (DEBUG(MAKE)) {
  432.         printf("update time: %s\n", Targ_FmtTime(cgn->mtime));
  433.     }
  434. #endif
  435.     }
  436.     
  437.     if (Lst_Open (cgn->parents) == SUCCESS) {
  438.     while ((ln = Lst_Next (cgn->parents)) != NILLNODE) {
  439.         pgn = (GNode *)Lst_Datum (ln);
  440.         if (pgn->make) {
  441.         pgn->unmade -= 1;
  442.  
  443.         if ( ! (cgn->type & (OP_EXEC|OP_USE))) {
  444.             if (cgn->made == MADE) {
  445.             pgn->childMade = TRUE;
  446.             if (pgn->cmtime < cgn->mtime) {
  447.                 pgn->cmtime = cgn->mtime;
  448.             }
  449.             } else {
  450.             (void)Make_TimeStamp (pgn, cgn);
  451.             }
  452.         }
  453.         if (pgn->unmade == 0) {
  454.             /*
  455.              * Queue the node up -- any unmade predecessors will
  456.              * be dealt with in MakeStartJobs.
  457.              */
  458.             (void)Lst_EnQueue (toBeMade, (ClientData)pgn);
  459.         } else if (pgn->unmade < 0) {
  460.             Error ("Graph cycles through %s", pgn->name);
  461.         }
  462.         }
  463.     }
  464.     Lst_Close (cgn->parents);
  465.     }
  466.     /*
  467.      * Deal with successor nodes. If any is marked for making and has an unmade
  468.      * count of 0, has not been made and isn't in the examination queue,
  469.      * it means we need to place it in the queue as it restrained itself
  470.      * before.
  471.      */
  472.     for (ln = Lst_First(cgn->successors); ln != NILLNODE; ln = Lst_Succ(ln)) {
  473.     GNode    *succ = (GNode *)Lst_Datum(ln);
  474.  
  475.     if (succ->make && succ->unmade == 0 && succ->made == UNMADE &&
  476.         Lst_Member(toBeMade, (ClientData)succ) == NILLNODE)
  477.     {
  478.         (void)Lst_EnQueue(toBeMade, (ClientData)succ);
  479.     }
  480.     }
  481.     
  482.     /*
  483.      * Set the .PREFIX and .IMPSRC variables for all the implied parents
  484.      * of this node.
  485.      */
  486.     if (Lst_Open (cgn->iParents) == SUCCESS) {
  487.     char    *cpref = Var_Value(PREFIX, cgn);
  488.  
  489.     while ((ln = Lst_Next (cgn->iParents)) != NILLNODE) {
  490.         pgn = (GNode *)Lst_Datum (ln);
  491.         if (pgn->make) {
  492.         Var_Set (IMPSRC, cname, pgn);
  493.         Var_Set (PREFIX, cpref, pgn);
  494.         }
  495.     }
  496.     Lst_Close (cgn->iParents);
  497.     }
  498. }
  499.  
  500. /*-
  501.  *-----------------------------------------------------------------------
  502.  * MakeAddAllSrc --
  503.  *    Add a child's name to the ALLSRC and OODATE variables of the given
  504.  *    node. Called from Make_DoAllVar via Lst_ForEach. A child is added only
  505.  *    if it has not been given the .EXEC, .USE or .INVISIBLE attributes.
  506.  *    .EXEC and .USE children are very rarely going to be files, so...
  507.  *    A child is added to the OODATE variable if its modification time is
  508.  *    later than that of its parent, as defined by Make, except if the
  509.  *    parent is a .JOIN node. In that case, it is only added to the OODATE
  510.  *    variable if it was actually made (since .JOIN nodes don't have
  511.  *    modification times, the comparison is rather unfair...)..
  512.  *
  513.  * Results:
  514.  *    Always returns 0
  515.  *
  516.  * Side Effects:
  517.  *    The ALLSRC variable for the given node is extended.
  518.  *-----------------------------------------------------------------------
  519.  */
  520. static int
  521. MakeAddAllSrc (cgn, pgn)
  522.     GNode    *cgn;    /* The child to add */
  523.     GNode    *pgn;    /* The parent to whose ALLSRC variable it should be */
  524.             /* added */
  525. {
  526.     if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) {
  527.     register char *child;
  528.  
  529.     child = Var_Value(TARGET, cgn);
  530.     Var_Append (ALLSRC, child, pgn);
  531.     if (pgn->type & OP_JOIN) {
  532.         if (cgn->made == MADE) {
  533.         Var_Append(OODATE, child, pgn);
  534.         }
  535.     } else if ((pgn->mtime < cgn->mtime) ||
  536.            (cgn->mtime >= now && cgn->made == MADE))
  537.     {
  538.         /*
  539.          * It goes in the OODATE variable if the parent is younger than the
  540.          * child or if the child has been modified more recently than
  541.          * the start of the make. This is to keep pmake from getting
  542.          * confused if something else updates the parent after the
  543.          * make starts (shouldn't happen, I know, but sometimes it
  544.          * does). In such a case, if we've updated the kid, the parent
  545.          * is likely to have a modification time later than that of
  546.          * the kid and anything that relies on the OODATE variable will
  547.          * be hosed.
  548.          *
  549.          * XXX: This will cause all made children to go in the OODATE
  550.          * variable, even if they're not touched, if RECHECK isn't defined,
  551.          * since cgn->mtime is set to now in Make_Update. According to
  552.          * some people, this is good...
  553.          */
  554.         Var_Append(OODATE, child, pgn);
  555.     }
  556.     }
  557.     return (0);
  558. }
  559.  
  560. /*-
  561.  *-----------------------------------------------------------------------
  562.  * Make_DoAllVar --
  563.  *    Set up the ALLSRC and OODATE variables. Sad to say, it must be
  564.  *    done separately, rather than while traversing the graph. This is
  565.  *    because Make defined OODATE to contain all sources whose modification
  566.  *    times were later than that of the target, *not* those sources that
  567.  *    were out-of-date. Since in both compatibility and native modes,
  568.  *    the modification time of the parent isn't found until the child
  569.  *    has been dealt with, we have to wait until now to fill in the
  570.  *    variable. As for ALLSRC, the ordering is important and not
  571.  *    guaranteed when in native mode, so it must be set here, too.
  572.  *
  573.  * Results:
  574.  *    None
  575.  *
  576.  * Side Effects:
  577.  *    The ALLSRC and OODATE variables of the given node is filled in.
  578.  *    If the node is a .JOIN node, its TARGET variable will be set to
  579.  *     match its ALLSRC variable.
  580.  *-----------------------------------------------------------------------
  581.  */
  582. void
  583. Make_DoAllVar (gn)
  584.     GNode    *gn;
  585. {
  586.     Lst_ForEach (gn->children, MakeAddAllSrc, gn);
  587.  
  588.     if (!Var_Exists (OODATE, gn)) {
  589.     Var_Set (OODATE, "", gn);
  590.     }
  591.     if (!Var_Exists (ALLSRC, gn)) {
  592.     Var_Set (ALLSRC, "", gn);
  593.     }
  594.  
  595.     if (gn->type & OP_JOIN) {
  596.     Var_Set (TARGET, Var_Value (ALLSRC, gn), gn);
  597.     }
  598. }
  599.  
  600. /*-
  601.  *-----------------------------------------------------------------------
  602.  * MakeStartJobs --
  603.  *    Start as many jobs as possible.
  604.  *
  605.  * Results:
  606.  *    If the query flag was given to pmake, no job will be started,
  607.  *    but as soon as an out-of-date target is found, this function
  608.  *    returns TRUE. At all other times, this function returns FALSE.
  609.  *
  610.  * Side Effects:
  611.  *    Nodes are removed from the toBeMade queue and job table slots
  612.  *    are filled.
  613.  *
  614.  *-----------------------------------------------------------------------
  615.  */
  616. static Boolean
  617. MakeStartJobs ()
  618. {
  619.     register GNode    *gn;
  620.     
  621.     while (!Job_Full() && !Lst_IsEmpty (toBeMade)) {
  622.     gn = (GNode *) Lst_DeQueue (toBeMade);
  623.     if (DEBUG(MAKE)) {
  624.         printf ("Examining %s...", gn->name);
  625.     }
  626.     /*
  627.      * Make sure any and all predecessors that are going to be made,
  628.      * have been.
  629.      */
  630.     if (!Lst_IsEmpty(gn->preds)) {
  631.         LstNode ln;
  632.  
  633.         for (ln = Lst_First(gn->preds); ln != NILLNODE; ln = Lst_Succ(ln)){
  634.         GNode    *pgn = (GNode *)Lst_Datum(ln);
  635.  
  636.         if (pgn->make && pgn->made == UNMADE) {
  637.             if (DEBUG(MAKE)) {
  638.             printf("predecessor %s not made yet.\n", pgn->name);
  639.             }
  640.             break;
  641.         }
  642.         }
  643.         /*
  644.          * If ln isn't nil, there's a predecessor as yet unmade, so we
  645.          * just drop this node on the floor. When the node in question
  646.          * has been made, it will notice this node as being ready to
  647.          * make but as yet unmade and will place the node on the queue.
  648.          */
  649.         if (ln != NILLNODE) {
  650.         continue;
  651.         }
  652.     }
  653.     
  654.     numNodes--;
  655.     if (Make_OODate (gn)) {
  656.         if (DEBUG(MAKE)) {
  657.         printf ("out-of-date\n");
  658.         }
  659.         if (queryFlag) {
  660.         return (TRUE);
  661.         }
  662.         Make_DoAllVar (gn);
  663.         Job_Make (gn);
  664.     } else {
  665.         if (DEBUG(MAKE)) {
  666.         printf ("up-to-date\n");
  667.         }
  668.         gn->made = UPTODATE;
  669.         if (gn->type & OP_JOIN) {
  670.         /*
  671.          * Even for an up-to-date .JOIN node, we need it to have its
  672.          * context variables so references to it get the correct
  673.          * value for .TARGET when building up the context variables
  674.          * of its parent(s)...
  675.          */
  676.         Make_DoAllVar (gn);
  677.         }
  678.         
  679.         Make_Update (gn);
  680.     }
  681.     }
  682.     return (FALSE);
  683. }
  684.  
  685. /*-
  686.  *-----------------------------------------------------------------------
  687.  * MakePrintStatus --
  688.  *    Print the status of a top-level node, viz. it being up-to-date
  689.  *    already or not created due to an error in a lower level.
  690.  *    Callback function for Make_Run via Lst_ForEach.
  691.  *
  692.  * Results:
  693.  *    Always returns 0.
  694.  *
  695.  * Side Effects:
  696.  *    A message may be printed.
  697.  *
  698.  *-----------------------------------------------------------------------
  699.  */
  700. static int
  701. MakePrintStatus(gn, cycle)
  702.     GNode       *gn;        /* Node to examine */
  703.     Boolean     cycle;        /* True if gn->unmade being non-zero implies
  704.                  * a cycle in the graph, not an error in an
  705.                  * inferior */
  706. {
  707.     if (gn->made == UPTODATE) {
  708.     printf ("`%s' is up to date.\n", gn->name);
  709.     } else if (gn->unmade != 0) {
  710.     if (cycle) {
  711.         /*
  712.          * If printing cycles and came to one that has unmade children,
  713.          * print out the cycle by recursing on its children. Note a
  714.          * cycle like:
  715.          *    a : b
  716.          *    b : c
  717.          *    c : b
  718.          * will cause this to erroneously complain about a being in
  719.          * the cycle, but this is a good approximation.
  720.          */
  721.         if (gn->made == CYCLE) {
  722.         Error("Graph cycles through `%s'", gn->name);
  723.         gn->made = ENDCYCLE;
  724.         Lst_ForEach(gn->children, MakePrintStatus, (ClientData)TRUE);
  725.         gn->made = UNMADE;
  726.         } else if (gn->made != ENDCYCLE) {
  727.         gn->made = CYCLE;
  728.         Lst_ForEach(gn->children, MakePrintStatus, (ClientData)TRUE);
  729.         }
  730.     } else {
  731.         printf ("`%s' not remade because of errors.\n", gn->name);
  732.     }
  733.     }
  734.     return (0);
  735. }
  736.  
  737. /*-
  738.  *-----------------------------------------------------------------------
  739.  * Make_Run --
  740.  *    Initialize the nodes to remake and the list of nodes which are
  741.  *    ready to be made by doing a breadth-first traversal of the graph
  742.  *    starting from the nodes in the given list. Once this traversal
  743.  *    is finished, all the 'leaves' of the graph are in the toBeMade
  744.  *    queue.
  745.  *    Using this queue and the Job module, work back up the graph,
  746.  *    calling on MakeStartJobs to keep the job table as full as
  747.  *    possible.
  748.  *
  749.  * Results:
  750.  *    TRUE if work was done. FALSE otherwise.
  751.  *
  752.  * Side Effects:
  753.  *    The make field of all nodes involved in the creation of the given
  754.  *    targets is set to 1. The toBeMade list is set to contain all the
  755.  *    'leaves' of these subgraphs.
  756.  *-----------------------------------------------------------------------
  757.  */
  758. Boolean
  759. Make_Run (targs)
  760.     Lst             targs;    /* the initial list of targets */
  761. {
  762.     register GNode  *gn;    /* a temporary pointer */
  763.     register Lst    examine;     /* List of targets to examine */
  764.     int                errors;     /* Number of errors the Job module reports */
  765.  
  766.     toBeMade = Lst_Init (FALSE);
  767.  
  768.     examine = Lst_Duplicate(targs, NOCOPY);
  769.     numNodes = 0;
  770.     
  771.     /*
  772.      * Make an initial downward pass over the graph, marking nodes to be made
  773.      * as we go down. We call Suff_FindDeps to find where a node is and
  774.      * to get some children for it if it has none and also has no commands.
  775.      * If the node is a leaf, we stick it on the toBeMade queue to
  776.      * be looked at in a minute, otherwise we add its children to our queue
  777.      * and go on about our business. 
  778.      */
  779.     while (!Lst_IsEmpty (examine)) {
  780.     gn = (GNode *) Lst_DeQueue (examine);
  781.     
  782.     if (!gn->make) {
  783.         gn->make = TRUE;
  784.         numNodes++;
  785.         
  786.         /*
  787.          * Apply any .USE rules before looking for implicit dependencies
  788.          * to make sure everything has commands that should...
  789.          */
  790.         Lst_ForEach (gn->children, Make_HandleUse, (ClientData)gn);
  791.         Suff_FindDeps (gn);
  792.  
  793.         if (gn->unmade != 0) {
  794.         Lst_ForEach (gn->children, MakeAddChild, (ClientData)examine);
  795.         } else {
  796.         (void)Lst_EnQueue (toBeMade, (ClientData)gn);
  797.         }
  798.     }
  799.     }
  800.     
  801.     Lst_Destroy (examine, NOFREE);
  802.  
  803.     if (queryFlag) {
  804.     /*
  805.      * We wouldn't do any work unless we could start some jobs in the
  806.      * next loop... (we won't actually start any, of course, this is just
  807.      * to see if any of the targets was out of date)
  808.      */
  809.     return (MakeStartJobs());
  810.     } else {
  811.     /*
  812.      * Initialization. At the moment, no jobs are running and until some
  813.      * get started, nothing will happen since the remaining upward
  814.      * traversal of the graph is performed by the routines in job.c upon
  815.      * the finishing of a job. So we fill the Job table as much as we can
  816.      * before going into our loop. 
  817.      */
  818.     (void) MakeStartJobs();
  819.     }
  820.  
  821.     /*
  822.      * Main Loop: The idea here is that the ending of jobs will take
  823.      * care of the maintenance of data structures and the waiting for output
  824.      * will cause us to be idle most of the time while our children run as
  825.      * much as possible. Because the job table is kept as full as possible,
  826.      * the only time when it will be empty is when all the jobs which need
  827.      * running have been run, so that is the end condition of this loop.
  828.      * Note that the Job module will exit if there were any errors unless the
  829.      * keepgoing flag was given.
  830.      */
  831.     while (!Job_Empty ()) {
  832.     Job_CatchOutput ();
  833.     Job_CatchChildren (!usePipes);
  834.     (void)MakeStartJobs();
  835.     }
  836.  
  837.     errors = Job_End();
  838.  
  839.     /*
  840.      * Print the final status of each target. E.g. if it wasn't made
  841.      * because some inferior reported an error.
  842.      */
  843.     Lst_ForEach(targs, MakePrintStatus,
  844.         (ClientData)((errors == 0) && (numNodes != 0)));
  845.     
  846.     return (TRUE);
  847. }
  848.